//
//  CPJNetworkManager.swift
//  Sina
//
//  Created by yang on 2017/7/30.
//  Copyright © 2017年 成品家（北京）网路科技有限公司. All rights reserved.
//

import UIKit

import AFNetworking
import YYModel

//swift的枚举
enum CPJHttpMethod
{
    case POST
    case GET
}

class CPJNetworkManager: AFHTTPSessionManager {

    
    //单列
    //第一次访问的时候，执行闭包，并把结果保存在shared常量中
    static let shared: CPJNetworkManager = {
        
        let instance = CPJNetworkManager()
        
        //设置响应的反序列化支持的数据类型
        instance.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        return instance
    }()
    
    lazy var userAccount = CPJUserAccount()
    
    var userLogin: Bool
    {
        return userAccount.access_token != nil
    }
    
    
    ///拼接token方法
    ///
    /// - Parameters:
    ///   - method: 请求方法
    ///   - URLString: 请求URL
    ///   - parameters: 请求的参数字典
    ///   - name: 上传文件的数据字段名，默认是nil，不上传文件
    ///   - data: 上传文件的二进制数据，默认是nil，不上传文件
    ///   - completion: <#completion description#>
    func appendToken(method: CPJHttpMethod = .GET, URLString: String, parameters: [String: AnyObject]?, name: String? = nil, data: Data? = nil, completion:@escaping (_ jsonData: Any?,_ isSuccess: Bool)->())
    {
        //访问令牌，所有的网络请求，都基于此令牌（登录除外）
        guard let token = userAccount.access_token else {
            
            //FIXME:
            print("token 不存在，重新登录")
            
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: UserShouldLoginNotification), object: nil)
            
            completion(nil,false)
            return
        }
        var parameters = parameters
        
        if parameters == nil
        {
            parameters = [String: AnyObject]()
        }
        parameters!["access_token"] = token as AnyObject
        
        if let data = data,
            let name = name
        {
            //上传文件
            upload(URLString: URLString, parameters: parameters, data: data, name: name, completion: completion)
        }
        else
        {
            request(method: method, URLString: URLString, parameters: parameters, completion: completion)
        }
    }
    
    //上传文件用post方法，get方法只能获取文件
    
    /// 封装AFN的上传文件方法
    ///
    /// - Parameters:
    ///   - URLString: 请求URL
    ///   - parameters: 参数字典
    ///   - data: 要上传的二进制数据
    ///   - name: 服务器接收数据的字段名
    ///   - completion: 完成回调
    func upload(URLString: String, parameters: [String: AnyObject]?, data: Data, name: String, completion: @escaping(_ jsonData: Any?, _ isSuccess: Bool) -> ())
    {
        post(URLString, parameters: parameters, constructingBodyWith: { (formData) in
            
            /*
             data:要上传的二进制数据
             name：服务器接收数据的字段名
             fileName:保存在服务器的文件夹名
             mimeType：告诉服务器上传文件的类型，如果不想告诉，可以使用application/octet-stream
             */
            formData.appendPart(withFileData: data, name: name, fileName: "", mimeType: "application/octet-stream")
        }, progress: nil, success: { (_, jsonData) in
            //成功的回调
            
            completion(jsonData,true)
        }) { (task, error) in
            //失败的回调
    
            let code = (task?.response as? HTTPURLResponse)?.statusCode
            if code == 403
            {
                print("token 过期了")
                //发送通知
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: UserShouldLoginNotification), object: "bad Token")
            }
            print("网络请求错误：\(error)")
            completion(nil,false)
        }
    }
    /// 封装AFN的post、get网络请求
    ///
    /// - Parameters:
    ///   - method: 请求方法
    ///   - URLString: 请求URL
    ///   - parameters: 请求参数
    ///   - completion: 请求回调 jsonData（字典／数组） isSuccess（成功／失败）
    func request(method: CPJHttpMethod = .GET,URLString: String,parameters: [String: AnyObject]?,completion:@escaping (_ jsonData: Any?,_ isSuccess: Bool)->())
    {
        //成功的闭包
        let success = {(task: URLSessionDataTask,json: Any?) -> () in
           completion(json,true)
        }
        //失败的闭包
        let failure = {(task: URLSessionDataTask?,error: Error) -> () in
            
            if (task?.response as? HTTPURLResponse)?.statusCode == 403
            {
                print("token 过期了")
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: UserShouldLoginNotification), object: "token过期")
            }
            completion(nil,false)
        }
        
        if method == .GET
        {
           
            //get请求
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
        else
        {
            //post请求
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }
}
